-- 运营活动: 达标竞技


--[[
{
    cmd_id = 1, -- 命令id，用于批量停止、删除活动  
    act_id = 9, -- 活动id (9 宝石竞技)
    act_name = '宝石竞技', -- 活动名称
    act_desc = '达标其中某个活动则可以领取对应奖励', -- 活动描述
    beg_time = 1488956400,  -- 活动开始时间(unix timestamp)
    end_time = 1489042800,  -- 活动结束时间(unix timestamp)  
    config = { -- 配置数据
        BroadInfo = Lang.ScriptTips.Operation013,
        Awards =
        {
            {
                desc = Lang.Activity.operationExpDesc01,
                icon = 1,
                needValue = 400,      --获得奖励类型值得数量
                maxCount = 3,
                mailReward = 1,             --邮件奖励，不能领取
                awards = 
                {
                    { type = 0, id = 753, count = 1, quality = 0, strong = 0, bind = 1, },
                    { type = 0, id = 509, count = 10, quality = 0, strong = 0, bind = 1, },
                    { type = 0, id = 560, count = 1, quality = 0, strong = 0, bind = 1, },
                },
            },
            {
                desc = Lang.Activity.operationExpDesc02,
                icon = 2,
                needValue = 300,      --获得奖励类型值得数量
                needBroadcast = true,
                maxCount = 10,
                awards = 
                {
                    { type = 0, id = 509, count = 6, quality = 0, strong = 0, bind = 1, },
                    { type = 0, id = 763, count = 200, quality = 0, strong = 0, bind = 1, },
                },
            },
            {
                desc = Lang.Activity.operationExpDesc03,
                icon = 3,
                needValue = 200,      --获得奖励类型值得数量
                needBroadcast = true,
                maxCount = 30,
                awards = 
                {
                    { type = 0, id = 509, count = 3, quality = 0, strong = 0, bind = 1, },
                    { type = 0, id = 763, count = 100, quality = 0, strong = 0, bind = 1, },
                },
            },
            {
                desc = Lang.Activity.operationExpDesc04,
                icon = 4,
                needValue = 100,      --获得奖励类型值得数量,
                needBroadcast = true,
                maxCount = 60,--配置为-1不限制数量
                awards = 
                {
                    { type = 0, id = 509, count = 1, quality = 0, strong = 0, bind = 1, },
                    { type = 0, id = 763, count = 50, quality = 0, strong = 0, bind = 1, },
                },
            },
            {
                desc = Lang.Activity.operationExpDesc05,
                icon = 6,
                needValue = 50,      --获得奖励类型值得数量
                needBroadcast = true,
                maxCount = -1,--配置为-1不限制数量
                awards = 
                {
                    { type = 0, id = 508, count = 1, quality = 0, strong = 0, bind = 1, },
                    { type = 0, id = 514, count = 1, quality = 0, strong = 0, bind = 1, },
                },
            },
        },
    },
}
]]

-- 检查配置是否正确，正确则返回 0，否则返回错误码
function oper_act_21_check_cfg(cfg)
	if cfg == nil then return 20 end
    
    local config = cfg.config
    if config == nil then return 21 end
    
    if config.Awards == nil then return 23 end
    if type(config.Awards) ~= "table" then return 24 end
    for idx = 1, #config.Awards do
        local dayRewards = config.Awards[idx]
        if dayRewards == nil then return 25 end
        if type(dayRewards) ~= "table" then return 26 end
        if dayRewards.awards == nil then return 27 end
        if type(dayRewards.awards) ~= "table" then return 28 end
        if not oper_act_check_one_award_cfg(dayRewards.awards) then
            return 22
        end 
    end

    return 0
end

-- 安装活动，成功则返回 0，否则返回错误码
function oper_act_21_setup(cfg)	
	return 0
end

-- 卸载活动
function oper_act_21_unsetup(cfg)	
end

-- 活动开始
function oper_act_21_start(cfg)
	local ssVar = System.getStaticVar()
    ssVar.oper_act_21_start = 1
	ssVar.oper_act_21_cmd = cfg.cmd_id
	ssVar.oper_act_21_act = cfg.act_id

    local data = gRankMgr_GetValueByIndx(0, RANK_DEFINE_OPERATION_21, 1)

    local needClearState = true

    local crossDayState = false

    if data then
        local myData = BaseFuc_unserialize(data)
        if myData and myData.cmd_id and myData.cmd_id == cfg.cmd_id and myData.act_id and myData.act_id == cfg.act_id and
            myData.time and cfg.beg_time <= myData.time and  cfg.end_time > myData.time then
            needClearState = false
            local time = System.getSystemTime()
            if myData and myData.mySelfTime and not System.isUnixTimeSameDay(myData.mySelfTime, time) then
                crossDayState = true
            end
        end
    end

    if crossDayState then
        if cfg then
            local config = cfg.config
            if config then 
                local firstData = GetOperationFirstData(cfg.act_id)
                if firstData and firstData.actorId and not firstData.reward then

                    local nIndex = 1

                    local subAwards = config.Awards[nIndex]
                    if  not subAwards  then
                        return
                    end
                    local hadSendCount = GetOperationVar(cfg.act_id, nIndex) or 0
                    if subAwards.maxCount == -1 or hadSendCount < subAwards.maxCount then --可以领
                        if subAwards.mailReward and subAwards.mailReward == 1 then
                            local title, content =  Lang.ScriptTips.Operation074, Lang.ScriptTips.Operation075
                            firstData.reward = 1
                            Awards.GiveToMailById(firstData.actorId, subAwards.awards, title, content, LogIds.OperationLogId021, Lang.LogTips.Operation021, firstData.vocation, firstData.sex)
                        end
                    end
                end
            end
        end
    end

    if needClearState or crossDayState then
        ClearOperationVar(cfg.act_id)
        gRankMgr_Clear(RANK_DEFINE_OPERATION_21)
    end
end

-- 活动结束
function oper_act_21_end(cfg)
	local ssVar = System.getStaticVar()
	ssVar.oper_act_21_start = nil
	ssVar.oper_act_21_cmd = nil
	ssVar.oper_act_21_act = nil

	if not cfg then return end
	local config = cfg.config
	if not config then return end

    local firstData = GetOperationFirstData(cfg.act_id)
	if firstData and firstData.actorId and not firstData.reward then

		local nIndex = 1

		local subAwards = config.Awards[nIndex]
		if  not subAwards  then
			return
		end
		local hadSendCount = GetOperationVar(cfg.act_id, nIndex) or 0
		if subAwards.maxCount == -1 or hadSendCount < subAwards.maxCount then --可以领
			if subAwards.mailReward and subAwards.mailReward == 1 then
				local title, content =  Lang.ScriptTips.Operation074, Lang.ScriptTips.Operation075
				firstData.reward = 1
				Awards.GiveToMailById(firstData.actorId, subAwards.awards, title, content, LogIds.OperationLogId021, Lang.LogTips.Operation021, firstData.vocation, firstData.sex)
			end
		end
	end
end

-- 打包数据
function oper_act_21_packet_data(sysarg, cfg)
	if not cfg then return end
	local config = cfg.config
	if not config then return end
	
	local actorid = Actor.getActorId(sysarg)
    local data = gRankMgr_GetValueById(actorid, RANK_DEFINE_OPERATION_21, 1)

    local myData = BaseFuc_unserialize(data)
    

    if not myData then
        myData = {}
    end

    if not myData.myValue then
        myData.myValue = 0
    end
    if not myData.myStateData then
        myData.myStateData = {}
    end
    
	local npack = oper_act_alloc_init_data_packet(sysarg, cfg.cmd_id, cfg.act_id)
    if (npack == nil) then
        return
    end
    DataPack.writeUInt(npack, myData.myValue)
	DataPack.writeByte(npack, #config.Awards)
	for k,v in pairs(config.Awards) do
		DataPack.writeByte(npack, k)
		local awardState = myData.myStateData[k] or 0
		local count = GetOperationVar(cfg.act_id, k)
		local leftCount = v.maxCount - (count or 0)
		if v.maxCount == -1 then
			leftCount = -1
		end
		DataPack.writeByte(npack, awardState)
		DataPack.writeShort(npack, leftCount)
	end

	local firstData = GetOperationFirstData(cfg.act_id)
	local firstName
	local firstId
	if firstData then
		firstName = firstData.actorName or ""
		firstId = firstData.actorId or 0
	else
		firstName = ""
		firstId = 0
	end
	
	DataPack.writeString(npack, firstName)
	DataPack.writeUInt(npack, firstId)

	DataPack.flush(npack) 
end

-- 操作，返回操作结果，0为成功
function oper_act_21_do(sysarg, cfg, clientPkt)
	if cfg == nil then return end
	
	if cfg.state == nil or cfg.state ~= 1 then -- 不在活动中
		Actor.sendTipmsg(sysarg,Lang.ScriptTips.Operation001, ttFlyTip)
		return
	end
	
	local config = cfg.config
	if config == nil then -- 参数错误
		print("error, oper_act_21_do cfg.config confg error")
		return
	end

	local nIndex = DataPack.readByte( clientPkt )


	local actorid = Actor.getActorId(sysarg)
    local data = gRankMgr_GetValueById(actorid, RANK_DEFINE_OPERATION_21, 1)

    local myData = BaseFuc_unserialize(data)
    

    if not myData then
        myData = {}
    end

    if not myData.myValue then
        myData.myValue = 0
    end
    if not myData.myStateData then
        myData.myStateData = {}
    end

	local subAwards = config.Awards[nIndex]
	if  not subAwards  then
		return
	end
	if subAwards.mailReward and subAwards.mailReward == 1 then
		Actor.sendTipmsg(sysarg, Lang.ScriptTips.Operation022, ttFlyTip)
		return 
	end
	local hadSendCount = GetOperationVar(cfg.act_id, nIndex)

	local result = 0

	if subAwards.maxCount == -1 or hadSendCount < subAwards.maxCount then --可以领
		local awardState = myData.myStateData[nIndex] or 0
		if awardState == 1 then
			if not Awards.CheckBagGridCount(sysarg, subAwards.awards) then
				Actor.sendTipmsg(sysarg, Lang.ScriptTips.COM0015, ttFlyTip)
				return
			end
			Awards.Give(sysarg,subAwards.awards,LogIds.OperationLogId021,Lang.LogTips.Operation021)
			SetOperationVar(cfg.act_id, nIndex, hadSendCount + 1)
			myData.myStateData[nIndex] = 2

            local time = System.getSystemTime()
            if not myData.cmd_id then
                myData.cmd_id = cfg.cmd_id
                myData.act_id = cfg.act_id
                myData.time = time
            end

            myData.mySelfTime = time

			local newData = BaseFuc_serialize(myData)
    		gRankMgr_SetRankEx(actorid, RANK_DEFINE_OPERATION_21, 1, newData)

			local msg = string.format(Lang.ScriptTips.Operation073, Actor.getName(sysarg), subAwards.needValue)
			System.broadcastTipmsg(msg,ttScreenCenter + ttChatWindow)
		end
	elseif hadSendCount >= subAwards.maxCount then
		result = 1
		Actor.sendTipmsg(sysarg, Lang.ScriptTips.Operation021, ttFlyTip)
	end
		
	
	local netPack = oper_act_alloc_do_result_packet(sysarg, cfg.cmd_id, cfg.act_id, result)
	DataPack.flush(netPack)


	oper_act_21_packet_data(sysarg, cfg)
end

-- 跨天
function oper_act_21_new_day_arrive(act_id)	
	local ssVar = System.getStaticVar()
    if not ssVar.oper_act_21_start then
        return
    end
    if not ssVar.oper_act_21_cmd then
        return
    end
    if not ssVar.oper_act_21_act then
        return
    end
    
    local cfg = get_oper_act_cfg(ssVar.oper_act_21_cmd, ssVar.oper_act_21_act)
    if not cfg then
        return
    end

    local config = cfg.config
    if not config then
        return
    end 

    local firstData = GetOperationFirstData(cfg.act_id)
    if firstData and firstData.actorId and not firstData.reward then

        local nIndex = 1

        local subAwards = config.Awards[nIndex]
        if  not subAwards  then
            return
        end
        local hadSendCount = GetOperationVar(cfg.act_id, nIndex) or 0
        if subAwards.maxCount == -1 or hadSendCount < subAwards.maxCount then --可以领
            if subAwards.mailReward and subAwards.mailReward == 1 then
                local title, content =  Lang.ScriptTips.Operation074, Lang.ScriptTips.Operation075
                firstData.reward = 1
                Awards.GiveToMailById(firstData.actorId, subAwards.awards, title, content, LogIds.OperationLogId021, Lang.LogTips.Operation021, firstData.vocation, firstData.sex)
            end
        end
    end

    ClearOperationVar(cfg.act_id)
    gRankMgr_Clear(RANK_DEFINE_OPERATION_21)   
end

function oper_act_21_get_value_arrive(sysarg, value)
    if value <= 0 then
        return
    end

	local ssVar = System.getStaticVar()
	if not ssVar.oper_act_21_start then
		return
	end
	if not ssVar.oper_act_21_cmd then
		return
	end
	if not ssVar.oper_act_21_act then
		return
	end
	
	local cfg = get_oper_act_cfg(ssVar.oper_act_21_cmd, ssVar.oper_act_21_act)
	if not cfg then
		return
	end

	local config = cfg.config
	if not config then
		return
	end	

    local actorid = Actor.getActorId(sysarg)
    local data = gRankMgr_GetValueById(actorid, RANK_DEFINE_OPERATION_21, 1)

    local myData = BaseFuc_unserialize(data)

    if not myData then
        myData = {}
    end
    if not myData.myValue then
        myData.myValue = 0
    end
    myData.myValue = myData.myValue + value
    if not myData.myStateData then
        myData.myStateData = {}
    end

	local sendData = false
	for k,v in pairs(config.Awards) do
		if myData.myValue >= v.needValue then
			local awardState = myData.myStateData[k] or 0
			if awardState == 0 then --还未完成
				myData.myStateData[k] = 1
				sendData = true
			end
		end
	end
    local time = System.getSystemTime()
    if not myData.cmd_id then
        myData.cmd_id = cfg.cmd_id
        myData.act_id = cfg.act_id
        myData.time = time
    end

    myData.mySelfTime = time

	local newData = BaseFuc_serialize(myData)
    gRankMgr_SetRankEx(actorid, RANK_DEFINE_OPERATION_21, 1, newData)

	local setState, oldActId = SetOperationFirstData(sysarg, cfg, myData.myValue)

	if sendData or (setState and setState == true) then
		oper_act_21_packet_data(sysarg, cfg)
	end

    if oldActId and setState then
        --print("oldActId = "..oldActId)
        oldSysarg = Actor.getActorById(oldActId)
        if oldSysarg then
            --print("oldActId sendData here")
            oper_act_21_packet_data(oldSysarg, cfg)
        end
    end
end

